#include "Cube3D.h"

Cube3D::Cube3D()
{
	color = Color(1.0f, 0.0f, 0.0f);
	numIndices = 36;
	texture = -1;
	castShadow = true;
	receiveShadow = true;


	float cubeVerts[] =
	{
		-0.5f, -0.5f, -0.5f,
		-0.5f, -0.5f,  0.5f,
		0.5f, -0.5f,  0.5f,
		0.5f, -0.5f, -0.5f,
		-0.5f,  0.5f, -0.5f,
		-0.5f,  0.5f,  0.5f,
		0.5f,  0.5f,  0.5f,
		0.5f,  0.5f, -0.5f,
		-0.5f, -0.5f, -0.5f,
		-0.5f,  0.5f, -0.5f,
		0.5f,  0.5f, -0.5f,
		0.5f, -0.5f, -0.5f,
		-0.5f, -0.5f, 0.5f,
		-0.5f,  0.5f, 0.5f,
		0.5f,  0.5f, 0.5f, 
		0.5f, -0.5f, 0.5f,
		-0.5f, -0.5f, -0.5f,
		-0.5f, -0.5f,  0.5f,
		-0.5f,  0.5f,  0.5f,
		-0.5f,  0.5f, -0.5f,
		0.5f, -0.5f, -0.5f,
		0.5f, -0.5f,  0.5f,
		0.5f,  0.5f,  0.5f,
		0.5f,  0.5f, -0.5f,
	};

	float cubeNormals[] =
	{
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
	};

	float cubeTex[] =
	{
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		1.0f, 0.0f,
		1.0f, 1.0f,
		0.0f, 1.0f,
		0.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f,
	};

	unsigned char cubeIndices[] =
	{
		0, 2, 1,
		0, 3, 2, 
		4, 5, 6,
		4, 6, 7,
		8, 9, 10,
		8, 10, 11, 
		12, 15, 14,
		12, 14, 13, 
		16, 17, 18,
		16, 18, 19, 
		20, 23, 22,
		20, 22, 21
	};

	GraphicsManager *graphics = GraphicsManager::GetGraphicsManager();

	vertices = graphics->CreateBuffer(cubeVerts, sizeof(cubeVerts));
	normals = graphics->CreateBuffer(cubeNormals, sizeof(cubeNormals));
	texCoords = graphics->CreateBuffer(cubeTex, sizeof(cubeTex));

	indices = new unsigned char[numIndices];
	memcpy(indices, cubeIndices, sizeof(cubeIndices));
};

Cube3D::~Cube3D()
{
	GraphicsManager *graphics = GraphicsManager::GetGraphicsManager();
	SAFE_DEL_ARRAY(indices);
};

void Cube3D::ApplyEffect(ObjectManager* objectManager, GraphicsManager *graphics)
{
	graphics->SetColor(shader3d::UN_LIGHTAMBIENT, objectManager->lightSource.ambient);
	graphics->SetColor(shader3d::UN_LIGHTDIFFUSE, objectManager->lightSource.diffuse);
	graphics->SetColor(shader3d::UN_LIGHTSPECULAR, objectManager->lightSource.specular);
	graphics->SetPosition(shader3d::UN_LIGHTPOSITION, objectManager->lightSource.position);
	graphics->SetPosition(shader3d::UN_CAMERA, objectManager->camera.position);
	graphics->SetMatrix(shader3d::UN_WORLDMATRIX, transformMatrix);
	if (texture >= 0)
	{
		graphics->SetInt(shader3d::UN_USETEXTURE, 1);
		graphics->SetTexture(shader3d::UN_MATERIALMAP, *ResourcesManager::GetResourcesManager()->GetTexture(texture), 1);
	}
	else
	{
		graphics->SetInt(shader3d::UN_USETEXTURE, 0);
	}

	graphics->SetColor(shader3d::UN_MATERIALDIFFUSE, material.diffuse);

	graphics->SetFloat(shader3d::UN_SHININESS, 2.0f);
};

void Cube3D::Render(ObjectManager* objectManager, GraphicsManager *graphics, Matrix* viewProjection, Matrix* lightVP, bool useEffect)
{
	Matrix wvpMatrix = *viewProjection;
	Matrix lightWVP = *lightVP;
	char tmpOption[3]={0,1,2};
	Matrix *transform = GetTransform(tmpOption);
	wvpMatrix*= *transform;
	lightWVP*= *transform;
	graphics->SetInt(shader3d::UN_USELIGHTING, objectManager->useLight);
	graphics->SetMatrix(shader3d::UN_WVPMATRIX, wvpMatrix);
	graphics->SetMatrix(shader3d::UN_LIGHTWVP, lightWVP);
	ApplyEffect(objectManager, graphics); 
	graphics->SetAttribute(ATTRIB_POSITION, vertices);
	graphics->SetAttribute(ATTRIB_NORMAL, normals);
	graphics->SetAttribute(ATTRIB_TEXCOORD, texCoords, 2);
	glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_BYTE, indices);
};
